home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / fountain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  13.3 KB  |  539 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)fountain.c    3.1    93/05/18    */
  2. /*    Copyright Scott R. Turner, srt@ucla, 10/27/86 */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* Code for drinking from fountains. */
  6.  
  7. #include "hack.h"
  8.  
  9. static void NDECL(dowatersnakes);
  10. static void NDECL(dowaterdemon);
  11. static void NDECL(dowaternymph);
  12. STATIC_PTR void FDECL(gush, (int,int,genericptr_t));
  13. static void NDECL(dofindgem);
  14.  
  15. static void
  16. dowatersnakes() /* Fountain of snakes! */
  17. {
  18.     register int num = rn1(5,2);
  19.     struct monst *mtmp;
  20.  
  21.     if (!(mons[PM_WATER_MOCCASIN].geno & (G_GENOD | G_EXTINCT))) {
  22.     if (!Blind)
  23.         pline("An endless stream of %s pours forth!",
  24.           Hallucination ? makeplural(rndmonnam()) : "snakes");
  25.     else
  26.         You("hear something hissing!");
  27.     while(num-- > 0)
  28.         if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy)) &&
  29.            t_at(mtmp->mx, mtmp->my))
  30.         (void) mintrap(mtmp);
  31.     } else
  32.     pline("The fountain bubbles furiously for a moment, then calms.");
  33. }
  34.  
  35. static
  36. void
  37. dowaterdemon() /* Water demon */
  38. {
  39.     register struct monst *mtmp;
  40.  
  41.     if(mons[PM_WATER_DEMON].geno & (G_GENOD | G_EXTINCT)) return;
  42.     if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy))) {
  43.         if (!Blind)
  44.         You("unleash %s!", a_monnam(mtmp));
  45.         else
  46.         You("feel the presence of evil.");
  47.  
  48.     /* Give those on low levels a (slightly) better chance of survival */
  49.         if (rnd(100) > (80 + level_difficulty())) {
  50.         pline("Grateful for %s release, %s grants you a wish!",
  51.               his[pronoun_gender(mtmp)], he[pronoun_gender(mtmp)]);
  52.         makewish();
  53.         mongone(mtmp);
  54.         } else if (t_at(mtmp->mx, mtmp->my))
  55.         (void) mintrap(mtmp);
  56.     }
  57. }
  58.  
  59. static void
  60. dowaternymph() /* Water Nymph */
  61. {
  62.     register struct monst *mtmp;
  63.  
  64.     if(mons[PM_WATER_NYMPH].geno & (G_GENOD | G_EXTINCT)) return;
  65.     if((mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy))) {
  66.         if (!Blind)
  67.            You("attract %s!", a_monnam(mtmp));
  68.         else
  69.            You("hear a seductive voice.");
  70.         mtmp->msleep = 0;
  71.         if (t_at(mtmp->mx, mtmp->my))
  72.             (void) mintrap(mtmp);
  73.     } else
  74.         if (!Blind)
  75.            pline("A large bubble rises to the surface and pops.");
  76.         else
  77.            You("hear a loud pop.");
  78. }
  79.  
  80. void
  81. dogushforth(drinking) /* Gushing forth along LOS from (u.ux, u.uy) */
  82. int drinking;
  83. {
  84.     int madepool = 0;
  85.  
  86.     do_clear_area(u.ux, u.uy, 7, gush, (genericptr_t)&madepool);
  87.     if (!madepool)
  88.         if (drinking)
  89.         Your("thirst is quenched.");
  90.         else
  91.         pline("Water sprays all over you.");
  92. }
  93.  
  94. STATIC_PTR void
  95. gush(x, y, poolcnt)
  96. int x, y;
  97. genericptr_t poolcnt;
  98. {
  99.     register struct monst *mtmp;
  100.  
  101.     if (((x+y)%2) || (x == u.ux && y == u.uy) ||
  102.         (rn2(1 + distmin(u.ux, u.uy, x, y)))  ||
  103.         (levl[x][y].typ != ROOM) || t_at(x,y) ||
  104.         (sobj_at(BOULDER, x, y)) || nexttodoor(x, y))
  105.         return;
  106.  
  107.     if (!((*(int *)poolcnt)++))
  108.         pline("Water gushes forth from the overflowing fountain!");
  109.  
  110.     /* Put a pool at x, y */
  111.     levl[x][y].typ = POOL;
  112.     del_engr_at(x, y);
  113.     water_damage(level.objects[x][y], FALSE, TRUE);
  114.  
  115.     if ((mtmp = m_at(x, y)) != 0)
  116.         (void) minwater(mtmp);
  117.     else
  118.         newsym(x,y);
  119. }
  120.  
  121. static void
  122. dofindgem() /* Find a gem in the sparkling waters. */
  123. {
  124.     if (!Blind) You("spot a gem in the sparkling waters!");
  125.     (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1),
  126.                         u.ux, u.uy, FALSE);
  127.     levl[u.ux][u.uy].looted |= F_LOOTED;
  128.     newsym(u.ux, u.uy);
  129.     exercise(A_WIS, TRUE);            /* a discovery! */
  130. }
  131.  
  132. void
  133. dryup(x,y)
  134. xchar x, y;
  135. {
  136.     boolean isyou = (x == u.ux && y == u.uy);
  137.  
  138.     if (IS_FOUNTAIN(levl[x][y].typ) &&
  139.         (!rn2(3) || (levl[x][y].looted & F_WARNED))) {
  140.         s_level *slev = Is_special(&u.uz);
  141.         if(isyou && slev && slev->flags.town &&
  142.            !(levl[x][y].looted & F_WARNED)) {
  143.             struct monst *mtmp;
  144.             levl[x][y].looted |= F_WARNED;
  145.             /* Warn about future fountain use. */
  146.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  147.                 if((mtmp->data == &mons[PM_WATCHMAN] ||
  148.                 mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
  149.                    couldsee(mtmp->mx, mtmp->my) &&
  150.                    mtmp->mpeaceful) {
  151.                 pline("%s yells:", Amonnam(mtmp));
  152.                 verbalize("Hey, stop using that fountain!");
  153.                 break;
  154.                 }
  155.             }
  156.             /* You can see or hear this effect */
  157.             if(!mtmp) pline("The flow reduces to a trickle.");
  158.             return;
  159.         }
  160. #ifdef WIZARD
  161.         if (isyou && wizard) {
  162.             if (yn("Dry up fountain?") == 'n')
  163.                 return;
  164.         }
  165. #endif
  166.         if (cansee(x,y)) pline("The fountain dries up!");
  167.         levl[x][y].typ = ROOM;
  168.         levl[x][y].looted = 0;
  169.         levl[x][y].blessedftn = 0;
  170.         /* The location is seen if the hero/monster is invisible */
  171.         /* or felt if the hero is blind.             */
  172.         newsym(x, y);
  173.         level.flags.nfountains--;
  174.         if(isyou && slev && slev->flags.town)
  175.             (void) angry_guards(FALSE);
  176.     }
  177. }
  178.  
  179. void
  180. drinkfountain()
  181. {
  182.     /* What happens when you drink from a fountain? */
  183.     register boolean mgkftn = (levl[u.ux][u.uy].blessedftn == 1);
  184.     register int fate = rnd(30);
  185.  
  186.     if (Levitation) {
  187.         You("are floating high above the fountain.");
  188.         return;
  189.     }
  190.  
  191.     if (mgkftn && u.uluck >= 0 && fate >= 10) {
  192.         int i, ii, littleluck = (u.uluck < 4);
  193.  
  194.         pline("Wow!  This makes you feel great!");
  195.         /* blessed restore ability */
  196.         for (ii = 0; ii < A_MAX; ii++)
  197.             if (ABASE(ii) < AMAX(ii)) {
  198.             ABASE(ii) = AMAX(ii);
  199.             flags.botl = 1;
  200.             }
  201.         /* gain ability, blessed if "natural" luck is high */
  202.         i = rn2(A_MAX);        /* start at a random attribute */
  203.         for (ii = 0; ii < A_MAX; ii++) {
  204.             if (adjattrib(i, 1, littleluck ? -1 : 0) && littleluck)
  205.             break;
  206.             if (++i >= A_MAX) i = 0;
  207.         }
  208.         display_nhwindow(WIN_MESSAGE, FALSE);
  209.         pline("A wisp of vapor escapes the fountain...");
  210.         exercise(A_WIS, TRUE);
  211.         levl[u.ux][u.uy].blessedftn = 0;
  212.         return;
  213.     }
  214.  
  215.     if (fate < 10) {
  216.         pline("The cool draught refreshes you.");
  217.         u.uhunger += rnd(10); /* don't choke on water */
  218.         newuhs(FALSE);
  219.         if(mgkftn) return;
  220.     } else {
  221.         switch (fate) {
  222.  
  223.         case 19: /* Self-knowledge */
  224.  
  225.             You("feel self-knowledgeable...");
  226.             display_nhwindow(WIN_MESSAGE, FALSE);
  227.             enlightenment(FALSE);
  228.             exercise(A_WIS, TRUE);
  229.             pline("The feeling subsides.");
  230.             break;
  231.  
  232.         case 20: /* Foul water */
  233.  
  234.             pline("The water is foul!  You gag and vomit.");
  235.             morehungry(rn1(20, 11));
  236.             vomit();
  237.             break;
  238.  
  239.         case 21: /* Poisonous */
  240.  
  241.             pline("The water is contaminated!");
  242.             if (Poison_resistance) {
  243. #ifdef TUTTI_FRUTTI
  244.        pline("Perhaps it is runoff from the nearby %s farm.", pl_fruit);
  245. #else
  246.        pline("Perhaps it is runoff from the nearby orange farm.");
  247. #endif
  248.                losehp(rnd(4),"unrefrigerated sip of juice",
  249.                 KILLED_BY_AN);
  250.                break;
  251.             }
  252.             losestr(rn1(4,3));
  253.             losehp(rnd(10),"contaminated water", KILLED_BY);
  254.             exercise(A_CON, FALSE);
  255.             break;
  256.  
  257.         case 22: /* Fountain of snakes! */
  258.  
  259.             dowatersnakes();
  260.             break;
  261.  
  262.         case 23: /* Water demon */
  263.             dowaterdemon();
  264.             break;
  265.  
  266.         case 24: /* Curse an item */ {
  267.             register struct obj *obj;
  268.  
  269.             pline("This water's no good!");
  270.             morehungry(rn1(20, 11));
  271.             exercise(A_CON, FALSE);
  272.             for(obj = invent; obj ; obj = obj->nobj)
  273.                 if (!rn2(5))    curse(obj);
  274.             break;
  275.             }
  276.  
  277.         case 25: /* See invisible */
  278.  
  279.             You("see an image of someone stalking you.");
  280.             pline("But it disappears.");
  281.             HSee_invisible |= FROMOUTSIDE;
  282.             newsym(u.ux,u.uy);
  283.             exercise(A_WIS, TRUE);
  284.             break;
  285.  
  286.         case 26: /* See Monsters */
  287.  
  288.             (void) monster_detect((struct obj *)0, 0);
  289.             exercise(A_WIS, TRUE);
  290.             break;
  291.  
  292.         case 27: /* Find a gem in the sparkling waters. */
  293.  
  294.             if (!levl[u.ux][u.uy].looted) {
  295.                 dofindgem();
  296.                 break;
  297.             }
  298.  
  299.         case 28: /* Water Nymph */
  300.  
  301.             dowaternymph();
  302.             break;
  303.  
  304.         case 29: /* Scare */ {
  305.             register struct monst *mtmp;
  306.  
  307.             pline("This water gives you bad breath!");
  308.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  309.                 mtmp->mflee = 1;
  310.             }
  311.             break;
  312.  
  313.         case 30: /* Gushing forth in this room */
  314.  
  315.             dogushforth(TRUE);
  316.             break;
  317.  
  318.         default:
  319.  
  320.             pline("This tepid water is tasteless.");
  321.             break;
  322.         }
  323.     }
  324.     dryup(u.ux, u.uy);
  325. }
  326.  
  327. void
  328. dipfountain(obj)
  329. register struct obj *obj;
  330. {
  331.     if (Levitation) {
  332.         You("are floating high above the fountain.");
  333.         return;
  334.     }
  335.  
  336.     /* Don't grant Excalibur when there's more than one object.  */
  337.     /* (quantity could be > 1 if merged daggers got polymorphed) */
  338.     if (obj->otyp == LONG_SWORD && obj->quan == 1L
  339.         && u.ulevel >= 5 && !rn2(6)
  340.         && !obj->oartifact
  341.         && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
  342.         if (u.ualign.type != A_LAWFUL) {
  343.             /* Ha!  Trying to cheat her. */
  344.             pline("A freezing mist rises from the water and envelopes the sword.");
  345.             pline("The fountain disappears!");
  346.             curse(obj);
  347.             if (obj->spe > -6 && !rn2(3)) obj->spe--;
  348.             obj->oerodeproof = FALSE;
  349.             exercise(A_WIS, FALSE);
  350.         } else {
  351.             /* The lady of the lake acts! - Eric Backus */
  352.             /* Be *REAL* nice */
  353.       pline("From the murky depths, a hand reaches up to bless the sword.");
  354.             pline("As the hand retreats, the fountain disappears!");
  355.             obj = oname(obj, artiname(ART_EXCALIBUR), 1);
  356.             bless(obj);
  357.             obj->oeroded = 0;
  358.             obj->oerodeproof = TRUE;
  359.             exercise(A_WIS, TRUE);
  360.         }
  361.         levl[u.ux][u.uy].typ = ROOM;
  362.         levl[u.ux][u.uy].looted = 0;
  363.         if(Invisible) newsym(u.ux, u.uy);
  364.         level.flags.nfountains--;
  365.         return;
  366.     } else (void) get_wet(obj);
  367.  
  368.     switch (rnd(30)) {
  369.         case 16: /* Curse the item */
  370.             curse(obj);
  371.             break;
  372.         case 17:
  373.         case 18:
  374.         case 19:
  375.         case 20: /* Uncurse the item */
  376.             if(obj->cursed) {
  377.                 if (!Blind)
  378.                 pline("The water glows for a moment.");
  379.                 uncurse(obj);
  380.             } else {
  381.                 pline("A feeling of loss comes over you.");
  382.             }
  383.             break;
  384.         case 21: /* Water Demon */
  385.             dowaterdemon();
  386.             break;
  387.         case 22: /* Water Nymph */
  388.             dowaternymph();
  389.             break;
  390.         case 23: /* an Endless Stream of Snakes */
  391.             dowatersnakes();
  392.             break;
  393.         case 24: /* Find a gem */
  394.             dofindgem();
  395.             break;
  396.         case 25: /* Water gushes forth */
  397.             dogushforth(FALSE);
  398.             break;
  399.         case 26: /* Strange feeling */
  400.             pline("A strange tingling runs up your %s.",
  401.                             body_part(ARM));
  402.             break;
  403.         case 27: /* Strange feeling */
  404.             You("feel a sudden chill.");
  405.             break;
  406.         case 28: /* Strange feeling */
  407.             pline("An urge to take a bath overwhelms you.");
  408.             if (u.ugold > 10) {
  409.                 u.ugold -= somegold() / 10;
  410.                 You("lost some of your gold in the fountain!");
  411.                 levl[u.ux][u.uy].looted &= ~F_LOOTED;
  412.                 exercise(A_WIS, FALSE);
  413.             }
  414.             break;
  415.         case 29: /* You see coins */
  416.  
  417.         /* We make fountains have more coins the closer you are to the
  418.          * surface.  After all, there will have been more people going
  419.          * by.    Just like a shopping mall!  Chris Woodbury  */
  420.  
  421.             mkgold((long)
  422.             (rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
  423.             u.ux, u.uy);
  424.             if (!Blind)
  425.         pline("Far below you, you see coins glistening in the water.");
  426.             exercise(A_WIS, TRUE);
  427.             break;
  428.     }
  429.     dryup(u.ux, u.uy);
  430. }
  431.  
  432. #ifdef SINKS
  433. void
  434. breaksink(x,y)
  435. int x, y;
  436. {
  437.     if(cansee(x,y) || (x == u.ux && y == u.uy))
  438.     pline("The pipes break!  Water spurts out!");
  439.     level.flags.nsinks--;
  440.     levl[x][y].doormask = 0;
  441.     levl[x][y].typ = FOUNTAIN;
  442.     level.flags.nfountains++;
  443.     newsym(x,y);
  444. }
  445.  
  446. void
  447. drinksink()
  448. {
  449.     if (Levitation) {
  450.         You("are floating high above the sink.");
  451.         return;
  452.     }
  453.     switch(rn2(20)) {
  454.         static NEARDATA struct obj *otmp;
  455.         case 0: You("take a sip of very cold water.");
  456.             break;
  457.         case 1: You("take a sip of very warm water.");
  458.             break;
  459.         case 2: You("take a sip of scalding hot water.");
  460.             if (Fire_resistance)
  461.                 pline("It seems quite tasty.");
  462.             else losehp(rnd(6), "sipping boiling water", KILLED_BY);
  463.             break;
  464.         case 3: if (mons[PM_SEWER_RAT].geno & (G_GENOD | G_EXTINCT))
  465.                 pline("The sink seems quite dirty.");
  466.             else {
  467.                 static NEARDATA struct monst *mtmp;
  468.  
  469.                 mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy);
  470.                 pline("Eek!  There's %s in the sink!",
  471.                     Blind ? "something squirmy" :
  472.                     a_monnam(mtmp));
  473.             }
  474.             break;
  475.         case 4: do {
  476.                 otmp = mkobj(POTION_CLASS,FALSE);
  477.                 if (otmp->otyp == POT_WATER) {
  478.                     obfree(otmp, (struct obj *)0);
  479.                     otmp = (struct obj *) 0;
  480.                 }
  481.             } while(!otmp);
  482.             otmp->cursed = otmp->blessed = 0;
  483.             pline("Some %s liquid flows from the faucet.",
  484.                   Blind ? "odd" :
  485.                   Hallucination ? hcolor() :
  486.                   OBJ_DESCR(objects[otmp->otyp]));
  487.             otmp->dknown = !(Blind || Hallucination);
  488.             otmp->quan++; /* Avoid panic upon useup() */
  489.             otmp->corpsenm = 1; /* kludge for docall() */
  490.             (void) dopotion(otmp);
  491.             obfree(otmp, (struct obj *)0);
  492.             break;
  493.         case 5: if (!(levl[u.ux][u.uy].looted & S_LRING)) {
  494.                 You("find a ring in the sink!");
  495.                 (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE);
  496.                 levl[u.ux][u.uy].looted |= S_LRING;
  497.                 exercise(A_WIS, TRUE);
  498.             } else pline("Some dirty water backs up in the drain.");
  499.             break;
  500.         case 6: breaksink(u.ux,u.uy);
  501.             break;
  502.         case 7: pline("The water moves as though of its own will!");
  503.             if ((mons[PM_WATER_ELEMENTAL].geno & (G_GENOD | G_EXTINCT))
  504.                 || !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy))
  505.                 pline("But it quiets down.");
  506.             break;
  507.         case 8: pline("Yuk, this water tastes awful.");
  508.             more_experienced(1,0);
  509.             newexplevel();
  510.             break;
  511.         case 9: pline("Gaggg... this tastes like sewage!  You vomit.");
  512.             morehungry(rn1(30-ACURR(A_CON), 11));
  513.             vomit();
  514.             break;
  515.         case 10: pline("This water contains toxic wastes!");
  516.             You("undergo a freakish metamorphosis!");
  517. #ifdef POLYSELF
  518.             polyself();
  519. #else
  520.             newman();
  521. #endif
  522.             break;
  523.         /* more odd messages --JJB */
  524.         case 11: You("hear clanking from the pipes...");
  525.             break;
  526.         case 12: You("hear snatches of song from among the sewers...");
  527.             break;
  528.         case 19: if (Hallucination) {
  529.            pline("From the murky drain, a hand reaches up... --oops--");
  530.                 break;
  531.             }
  532.         default: You("take a sip of %s water.",
  533.             rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
  534.     }
  535. }
  536. #endif /* SINKS */
  537.  
  538. /*fountain.c*/
  539.